/**
* Oxide
*
* Copyright (c) 2011 Dinosaur Kick Pty Ltd, All rights reserved.
*
* This source code is made available under the "Modified BSD" licensing arrangement.
* See license.txt for details.
*/
// ----------------------------------------------------------------------------
#include <string>
#include <boost/make_shared.hpp>
#include <boost/lexical_cast.hpp>
#include "oxide-common/ast/ast.hpp"
#include "../cursor.hpp"
#include "cursor_incrementer.hpp"
#include "message_list.hpp"
#include "message.hpp"
#include "token_comparator.hpp"
#include "token_empty_predicate.hpp"
#include "precedence_map.hpp"
#include "result.hpp"
// ----------------------------------------------------------------------------
#ifndef O2_PARSE_PARSER_INC
#define O2_PARSE_PARSER_INC
namespace o2 {
namespace parse {
// ----------------------------------------------------------------------------

struct eof_error {};

template <typename IteratorT, typename StringT = typename std::iterator_traits<IteratorT>::value_type::string_type>
class basic_parser
{
	public:
		typedef IteratorT iterator_type;
		typedef StringT string_type;
		typedef typename std::iterator_traits<IteratorT>::value_type token_type;
		typedef basic_result<string_type> result_type;
		typedef basic_message<string_type> message_type;
		typedef basic_message_list<string_type> message_list_type;
		typedef detail::cursor_incrementer<IteratorT> incrementer_type;
		typedef detail::token_comparator<string_type> comparator_type;
		typedef detail::token_empty_predicate<string_type> empty_predicate_type;
		typedef cursor<iterator_type, incrementer_type, token_identity, comparator_type, empty_predicate_type> cursor_type;
		typedef boost::basic_format<typename string_type::value_type> format_type;

		O2_AST_TYPEDEFS(string_type);

		basic_parser(const iterator_type& begin, const iterator_type& end)
			: m_cursor(begin, end)
			{ }
		
		result_type parse()
		{
			try
			{
				return result_type(parse_primaries(), m_messages);
			}
			catch (const eof_error&)
			{
				error(O2_CSTR("Unexpected end of file."));
				return result_type(m_messages);
			}
		}

	private:
		#include "parser_class.ipp"
		#include "parser_class_member.ipp"
		#include "parser_error.ipp"
		#include "parser_expr.ipp"
		#include "parser_helpers.ipp"
		#include "parser_literals.ipp"
		#include "parser_primaries.ipp"
		#include "parser_stmt.ipp"

		message_list_type m_messages;
		cursor_type m_cursor;
		precedence_map m_precedence_map;
};

// ----------------------------------------------------------------------------
} // namespace parse
} // namespace o2
#endif // O2_PARSE_PARSER_INC
// ----------------------------------------------------------------------------
